const {
    reject
} = require('./underscore.js');

const wxLog = wx.getRealtimeLogManager ? wx.getRealtimeLogManager() : null;
const app = getApp();

/**
 * 本地存储
 */
const storage = {
    set: (key, value) => {
        return new Promise(function (resolve, reject) {
            wx.setStorage({
                key: key,
                data: value,
                success: function () {
                    resolve();
                },
                fail: function () {
                    reject();
                }
            })
        })
    },
    get: (key) => {
        return new Promise(function (resolve, reject) {
            wx.getStorage({
                key: key,
                success: function (res) {
                    if (res.data == '' || res.data == null) return reject()
                    resolve(res.data)
                },
                fail: function () {
                    reject();
                }
            })
        })
    },
    remove: (key) => {
        return new Promise(function (resolve, reject) {
            wx.removeStorage({
                key: key,
                success: function (res) {
                    resolve(res.data)
                },
                fail: function () {
                    reject();
                }
            })
        })
    },
    clear: () => {
        return wx.clearStorage()
    }
}

/**
 * 图片处理
 **/
const images = {
    preview: (current, urls) => {
        wx.previewImage({
            current: current, // 当前显示图片的http链接
            urls: urls // 需要预览的图片http链接列表
        })
    },
    choose: (count) => {
        return new Promise(function (resolve, reject) {
            wx.chooseImage({
                count: count, // 默认9
                sizeType: ['compressed'], // 可以指定是原图还是压缩图，默认二者都有
                sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机，默认二者都有
                success: function (res) {
                    resolve(res.tempFilePaths)
                },
                fail: function () {
                    reject();
                }
            })
        })
    },
    upload: (filePath, token, fileName) => {
        return new Promise(function (resolve, reject) {
            wx.uploadFile({
                url: 'https://up.qbox.me',
                filePath: filePath,
                name: 'file',
                formData: {
                    'key': fileName,
                    'token': token,
                },
                success: function (res) {
                    let data = JSON.parse(res.data);
                    resolve(`${data.key}`);
                },
                fail(error) {
                    reject();
                },
            });
        })
    }
}

/**
 * 拨打电话
 **/
const makePhone = (value) => {
    wx.makePhoneCall({
        phoneNumber: value
    })
}

/**
 * 返回到指定页
 * 若该页面不存在，则打开该页面
 * 打开方式 0为redirectTo   1为navigateTo   2为relaunch
 * 默认打开方式为：redirectTo
 */
const backToUri = {
    cancel: false,
    async handler({
        url = '',
        delay = 0,
        type = 0
    }) {
        let pages = getCurrentPages(),
            idx = getRouteStackUri(url);

        this.cancel = false;

        let handler = () => {
            //已被取消，不作响应
            if (this.cancel) return;
            //页面存在，返回到该页面
            if (idx > 0) {
                wx.navigateBack({
                    delta: pages.length - idx - 1
                });
            } else if (idx !== 0) {
                switch (type) {
                    case 0:
                        wx.redirectTo({
                            url
                        });
                        break;
                    case 1:
                        wx.navigateTo({
                            url
                        });
                        break;
                    case 2:
                        wx.reLaunch({
                            url
                        });
                        break;
                    default:
                        wx.redirectTo({
                            url
                        });
                }
            }
        };

        delay && await sleep(delay);

        handler();
    }
};

/**
 * 从页面栈获取指定页面
 */
const getRouteStackUri = (uri) => {
    let pages = getCurrentPages(),
        idx = -1,
        isAbsoluteUri = uri[0] === '/';

    if (!uri || !isAbsoluteUri) throw new Error('请填写正确页面的绝对路径');
    console.log('pages', pages)
    for (let i = 0; i < pages.length; i++) {
        let item = pages[i];

        if (item.route === uri.slice(1)) {
            idx = i;
            break;
        }
    }

    return idx;
};

/**
 * 获取登录状态
 */
const getLoginState = () => {
    return getApp().globalData.userInfo;
}

/**
 * 进入链接为分享链接
 * 分享后跳转至分享页面
 */
const checkShareUri = (options = {}) => {
    return new Promise((resolve, reject) => {
        let pages = getCurrentPages(),
            p = pages[pages.length - 1],
            page = p.route,
            uri = '',
            token = !!getLoginState();

        if (p.options.isShare === "true" && !token) {
            let query = '';

            for (let key in p.options) {
                if (key !== 'isShare') {
                    if ('' + p.options[key] !== "undefined") {
                        query += `&${key}=${p.options[key]}`;
                    }
                }
            }

            query = query.substr(1);
            uri = '/' + page + (query ? `?${query}` : '');

            //存储分享登录后跳转页面
            getApp().globalData.returnUrl = uri;
        }

        //已登录，或者未登录但分享的页面不需要登录即可查看时resolve
        if (token) {
            resolve();
        } else {
            //分享的是需要登录的页面，直接去登录
            if (options.needLogin) {
                return checkLoginState({
                    uri,
                    routeUri: 3,
                    routeLogin: 3,
                });
            }

            resolve();
        }
    })
}

/**
 * 退出登录
 */
const signOut = () => {
    let globalData = getApp().globalData,
        uuid = globalData.uuid,
        shareUserId = wx.getStorageSync('shareUserId') || '',
        serverTime = wx.getStorageSync('serverTime') || "";

    wx.clearStorage();
    wx.setStorageSync('uuid', uuid); //uuid不删除
    if (shareUserId) {
        wx.setStorageSync('shareUserId', shareUserId);
    }
    if (serverTime) {
        wx.setStorageSync('serverTime', serverTime);
    }
    globalData.authToken = '';
    globalData.userInfo = {};
    wx.reLaunch({
        url: globalData.homeUri
    });

    setNowTime();
}

// 获取当前设备时间，与当天00：00作比较，如果当前时间大于等于当天晚上凌晨，则表示第二天已到，换一张图
const setNowTime = () => {
    let date = new Date();
    let year = date.getFullYear(),
        month = date.getMonth() + 1,
        day = date.getDate();
    wx.setStorageSync('kkkDate', year + '-' + month + '-' + day)
    wx.setStorageSync('isCloseCheckin', true)
}

//防抖 间隔为1500毫秒
const throttle = (fn, gapTime) => {
    if (!gapTime) {
        gapTime = 1500
    }

    let lastTime = null;


    return function () {
        let nowTime = +new Date();
        if (nowTime - lastTime > gapTime || !lastTime) {
            fn.apply(this, arguments);
            lastTime = nowTime
        }
    }
}

//获取页面参数
const getQueryString = (url, name) => {
    let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"),
        uri = url.split('?')[1] || '',
        r = uri.match(reg);

    if (r != null) return unescape(r[2]);

    return null;
}

/**
 * 获取微信路由方法名
 */
const getWxRouteName = (type) => {
    let wxMethod = '';

    switch (type) {
        case 1:
            wxMethod = 'navigateTo';
            break;
        case 2:
            wxMethod = 'redirectTo';
            break;
        case 3:
            wxMethod = 'reLaunch';
            break;
        case 4:
            wxMethod = 'switchTab';
            break;
        case 5:
            wxMethod = 'navigateBack';
            break;
        default:
            wxMethod = 'navigateBack';
    }

    return wxMethod;
}

/**
 * 登录点检测
 * @param options
 */
const checkLoginState = (options) => {
    let routeUri = options.routeUri || 1, //默认navigate方式打开
        routeLogin = options.routeLogin || 1, //默认navigate方式打开
        pages = getCurrentPages(),
        p = pages[pages.length - 1],
        route = p.route,
        url = options.uri || '/' + route,
        wxMethod = getWxRouteName(routeLogin), // 跳转方式
        delta = options.delta;

    //未登录时跳转登录
    if (!getLoginState()) {
        console.log(">......");
        // wx[wxMethod]({
        //     // url: `/pages/login/login?toUri=${encodeURIComponent(url)}&routeType=${routeUri}`,
        //     url:"/pages/mine/mine",
        //     success() {
        //         options.callback && options.callback();
        //     }
        // });
        wx.switchTab({
          url: '/pages/mine/mine',
        })
    } else
        options.callback && options.callback();
}

//微信方法转promise
const wxMethod = {
    /**
     * 下载二维码图片
     */
    downloadQRCode(url) {
        let _this = this;

        return new Promise((resolve, reject) => {
            wx.downloadFile({
                url,
                success(e) {
                    resolve(e);
                },
                fail(e) {
                    reject();
                }
            });
        });
    },

    /**
     * 获取授权信息
     */
    getSetting(scope) {
        return new Promise((resolve, reject) => {
            wx.getSetting({
                scope,
                success(e) {
                    resolve(e);
                },
                fail(e) {
                    reject(e);
                }
            });
        });
    },

    /**
     * 保存图片到相册
     */
    saveToAlbum(filePath) {
        return new Promise((resolve, reject) => {
            wx.saveImageToPhotosAlbum({
                filePath,
                success() {
                    resolve();
                },
                fail(e) {
                    reject();
                }
            });
        });
    },

    /**
     * 订阅消息
     */
    requestSubscribeMessage(op) {
        return new Promise((resolve, reject) => {
            wx.requestSubscribeMessage({
                tmplIds: op.tmplIds,
                success: op.success,
                fail: op.fail,
                complete(res) {
                    console.log('授权请求完成', res);
                    op.complete && op.complete(res)
                    resolve();
                }
            })
        });
    },
}

/**
 * 等待n ms
 */
const sleep = (n) => {
    return new Promise((resolve, reject) => {
        let t = setTimeout(() => {
            //清除
            clearTimeout(t);

            resolve();
        }, n);
    });
};


/**
 * 微信实时日志
 * 正式环境上报
 */
const log = {
    info() {
        if (!getApp().globalData.isDev && wxLog)
            wxLog.info.apply(wxLog, arguments);
        else
            console.info.apply(console.info, arguments);
    },
    warn() {
        if (!getApp().globalData.isDev && wxLog)
            wxLog.warn.apply(wxLog, arguments);
        else
            console.warn.apply(console.warn, arguments);
    },
    error() {
        let app = getApp();

        if (!app.globalData.isDev && wxLog) {
            let args = [].slice.call(arguments);

            args.push(app.getHeader());

            wxLog.error.apply(wxLog, args);
        }

        console.error.apply(console.error, arguments);
    },
};

/**
 * 扫码进入逻辑处理
 */
const qrCodeHandle = (options) => {
    let q = options.q,
        globalData = getApp().globalData,
        scene = options.scene,
        utm_term = options.utm_term,
        utm_content = options.utm_content,
        setShare = (scene, crmuser, spreadId) => {
            globalData.share.scene = scene;
            globalData.share.crmuser = crmuser;
            globalData.share.spreadId = spreadId;
        };

    //普通链接二维码
    if (q) {
        let url = decodeURIComponent(options.q),
            crmuser = getQueryString(url, 'utm_term'),
            spreadId = getQueryString(url, 'utm_content');

        setShare(null, crmuser || '', +spreadId || 0);
        console.log(`扫描普通链接二维码进入,对应咨询师:${crmuser},对应推广码id:${spreadId}`);
    }
    //带参小程序二维码
    else if (utm_term) {
        setShare(null, utm_term, +utm_content || 0);
        console.log(`扫描带参小程序二维码进入,对应咨询师:${utm_term},对应推广码id:${utm_content}`);
    }
    //场景小程序二维码
    else if (scene) {
        let decode_scene = decodeURIComponent(scene), //decode后的options.scene可能形如utm_content=880
            spreadId = getQueryString(decode_scene, 'utm_content');

        //正常id的scene, 值如 a59f572b16154a428ac777b3b0b60354
        if (decode_scene.indexOf('=') === -1) {
            setShare(decode_scene, '', 0);
        }
        //非正常id的scene, 值如utm_content=880
        else {
            setShare(null, '', +spreadId || 0);
        }
        console.log(`扫描场景小程序二维码进入,对应场景值:${decode_scene}`);
    }
};

function copy(val) {
    wx.setClipboardData({
        data: String(val),
        success: () => wx.showToast({
            title: '复制成功',
            icon: 'none'
        }),
        fail: () => wx.showToast({
            title: '复制失败',
            icon: 'none'
        })
    });
}

function fullNumber(val) {
    if (val < 10) {
        return '0' + val
    }
    return val
}

function countdown(endTime, startTime) {
    const getTime = (time) => {
        if (!time) return new Date().getTime()

        if (typeof time === 'number') return time

        if (time instanceof Date) return time.getTime()

        return new Date(startTime.replace(/-/g, '/')).getTime()
    }

    startTime = getTime(startTime)
    endTime = getTime(endTime)

    const diffTime = endTime + 86400000 - startTime

    let days = parseInt(diffTime / (1000 * 60 * 60 * 24))
    let hours = parseInt((diffTime % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
    let minutes = parseInt((diffTime % (1000 * 60 * 60)) / (1000 * 60))
    let seconds = parseInt((diffTime % (1000 * 60)) / 1000)

    if (hours <= 0 && minutes <= 0 && seconds <= -1) {
        hours = 0
        minutes = 0
        seconds = 0
    }
    return {
        hours,
        minutes,
        seconds
    }
}

function oneDayCountdown(endTime, fomart = 'HH小时MM分钟SS秒') {
    const oneDay = 86400000
    const c = countdown(new Date(endTime.replace(/-/g, '/')).getTime() + oneDay)
    let isEnd = false

    const {
        hours,
        minutes,
        seconds
    } = c
    if (hours <= 0 && minutes <= 0 && seconds <= 0) {
        isEnd = true
    }
    return {
        isEnd,
        fomart: fomart.replace('HH', fullNumber(hours)).replace('MM', fullNumber(minutes)).replace('SS', fullNumber(seconds))
    }
}

function gotoPage(url, options) {
    wx.navigateTo({
        url
    })
    if (options) {
        const event = options.event ? options.event : 'MPclick'
        delete options.event
        const name = options.name
        options.$element_name = name
        delete options.name
        getApp().sensorsTrack(event, options)
    }
    // name && getApp().sensorsTrack('MPclick', { $title: title, $element_name: name })
}

function gotoChat(query, options) {
    wx.navigateTo({
        url: `/pages/web/chat/chat${query ? query : ''}`
    })
    getApp().sensorsTrack('ad_click', {
        page_type: options.page_type
    })
}

function subscribe(id, callback) {
    const tmplIds = id instanceof Array ? id : [id]
    wxMethod.requestSubscribeMessage({
        tmplIds,
        success: (res) => {
            if (res[id] && res[id] !== 'accept') {
                this.setData({
                    'subscribeModal.show': true
                })
            } else {
                // 循环引用问题。暂时处理
                // tmplIds.forEach(templateId => require('../api/base.js').addSubscribe({ openId: wx.getStorageSync('userinfo').OpenId, fromid: templateId }))

                callback && callback()
            }
        },
        fail: (err) => {
            log.error('获取订阅权限失败', err)
            err.errCode && this.setData({
                'subscribeModal.show': true
            })
        }
    });
}

// 时间戳转换成时间
const formatTime = date => {
    var date = new Date(date ? date : '') //一定要记得写这个，不然会报date.getFullYear is not a function
    const year = date.getFullYear()
    const month = date.getMonth() + 1
    const day = date.getDate()
    const hour = date.getHours()
    const minute = date.getMinutes()
    const second = date.getSeconds()

    return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}

const formatNumber = n => {
    n = n.toString()
    return n[1] ? n : '0' + n
}

const rpx2px = (rpx) => {
    return rpx / 750 * wx.getSystemInfoSync().windowWidth
}

const filePath2Base64 = (path) => {
    return new Promise((resolve, reject) => {
        wx.getFileSystemManager().readFile({
            filePath: path,
            encoding: 'base64',
            success(res) {
                resolve(res.data)
            },
            fail: reject
        });
    })
}

function isFullSucreen() {
    const res = wx.getSystemInfoSync()
    if (res.screenHeight - res.windowHeight - res.statusBarHeight - 32 > 72) {
        return true
    }
    if (res.model.search('iPhone X') !== -1) {
        return true
    }
    if (res.model.search('iPhone 1') !== -1) {
        return true
    }
    return false
}

function countdownTime(endTime, startTime) {
    const getTime = (time) => {
        if (!time) return new Date().getTime()

        if (typeof time === 'number') return time

        if (time instanceof Date) return time.getTime()

        return new Date(time.replace(/-/g, '/')).getTime()
    }

    startTime = getTime(startTime)
    endTime = getTime(endTime)

    const diffTime = endTime - startTime

    let fDays, fHours, fMinutes, fSeconds;

    let days = fDays = parseInt(diffTime / (1000 * 60 * 60 * 24))
    let hours = fHours = parseInt((diffTime % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
    let minutes = fMinutes = parseInt((diffTime % (1000 * 60 * 60)) / (1000 * 60))
    let seconds = fSeconds = parseInt((diffTime % (1000 * 60)) / 1000)

    if (days <= 0 && hours <= 0 && minutes <= 0 && seconds <= -1) {
        days = 0
        hours = 0
        minutes = 0
        seconds = 0
    }

    if (days < 10) {
        fDays = '0' + days
    }

    if (hours < 10) {
        fHours = '0' + hours
    }

    if (minutes < 10) {
        fMinutes = '0' + minutes
    }

    if (seconds < 10) {
        fSeconds = '0' + seconds
    }

    return {
        days,
        hours,
        minutes,
        seconds,
        fDays,
        fHours,
        fMinutes,
        fSeconds
    }
}

/**
 * 日期转换为时间戳
 * @param date 日期
 * @param type 位数
 * @return {number}
 */
function dateToTime(date, type = 10) {
    // 这里为了兼容IOS
    let time = new Date(date.replace(/-/g, '/')).getTime()
    if (type === 10) {
      return time / 1000
    } else {
      return time
    }
}


/**
 * 转换成日期
 * @param time
 * @param timeFormat
 * @return {{hour: string, day: string, minute: string, second: string}}
 */
function numberToCountDown(time, timeFormat = 40) {
    
    let second
    const callBackData = {
      day: '00',
      hour: '00',
      minute: '00',
      second: '00'
    }
    if (time.length === 13) {
      second = time / 1000
    } else {
      second = time
    }
  
    if (second < 0) {
      return callBackData
    }
  
    // 天位
    if (timeFormat >= 40) {
      const day = Math.floor(second / (3600 * 24))
      second = Math.floor(second % (3600 * 24))
  
      let dayStr = day.toString()
      if (dayStr.length === 1) dayStr = '0' + dayStr
      callBackData.day = dayStr
    }
  
    // 小时位
    if (timeFormat >= 30) {
      const hr = Math.floor(second / 3600)
      second = Math.floor(second % 3600)
  
      let hrStr = hr.toString()
      if (hrStr.length === 1) hrStr = '0' + hrStr
      callBackData.hour = hrStr
    }
  
    // 分钟位
    if (timeFormat >= 20) {
      const min = Math.floor(second / 60)
      second = Math.floor(second % 60)
  
      let minStr = min.toString()
      if (minStr.length === 1) minStr = '0' + minStr
      callBackData.minute = minStr
    }
  
    // 秒位
    if (timeFormat >= 10) {
      const sec = second
      let secStr = sec.toString()
      if (secStr.length === 1) secStr = '0' + secStr
      callBackData.second = secStr
    }
  
    return callBackData
}


module.exports = {
    storage,
    images,
    makePhone,
    checkShareUri,
    throttle,
    getQueryString,
    backToUri,
    getRouteStackUri,
    signOut,
    getLoginState,
    checkLoginState,
    getWxRouteName,
    wxMethod,
    log,
    sleep,
    qrCodeHandle,
    copy,
    countdown,
    oneDayCountdown,
    gotoPage,
    gotoChat,
    subscribe,
    formatTime,
    rpx2px,
    filePath2Base64,
    isFullSucreen,
    countdownTime,
    dateToTime,
    numberToCountDown
}